package com.ludomancy.sora;

import com.ludomancy.gamelib.MathHelper;
import com.ludomancy.gamelib.verlet.Circle;
import com.ludomancy.gamelib.verlet.Edge;
import com.ludomancy.gamelib.verlet.Vertex;

public class Game
{
	public static Game game;
	
	public Vertex player;
	public float targetX;
	public float targetY;
	
	// world
	public static float WIDTH = 1;
	public static float HEIGHT = 1;
	public static final float FLOOR = 0.95f;
		
	// physics
	public static final float GRAVITY = 0.000003f;
	public static final float AIR_FRICTION = 0.001f;
	public static final float SPEED = 0.003f;
	public static final int PHYSICS_ITERATIONS = 15;
	public static final float ARROW_RADII = 0.004f;
	public static final float PLAYER_TO_ARROW_FRICTION = 0.002f;
	public static final float ARROW_TO_ARROW_FRICTION = 0.001f;
	public static final float PLAYER_RADII = 0.01f;
	public SoraSimulation simulation;
	
	public boolean angry = false;
	public static boolean DEBUG = false;
	
	public Game(float width, float height)
	{
		game = this;
		WIDTH = width;
		HEIGHT = height;
		
		simulation = new SoraSimulation();
		
		// create player
		player = new Vertex(0.5f, 0.5f, PLAYER_RADII);
		simulation.addShape(new Circle(player));
		Building.create(simulation, 0.1f, FLOOR - 0.5f, 0.3f, 0.5f);
		Building.create(simulation, 0.6f, FLOOR - 0.3f, 0.3f, 0.3f);
		Car.create(simulation, 1, FLOOR-0.1f, 0.1f, 0.1f);
	}
	
	public void setTarget(float x, float y)
	{
		targetX = x;
		targetY = y;
	}
			
	public void update()
	{
		for (int i = 0; i < PHYSICS_ITERATIONS; i++)
		{
			updatePlayer();
			simulation.update();
		}
	}
	
	private void updatePlayer()
	{
		player.stop();
		// find dir
		float dirX = targetX - player.px;
		float dirY = targetY - player.py;
		if(MathHelper.dist(0, 0, dirX, dirY) < SPEED)
		{
			player.px = targetX;
			player.py = targetY;
		}
		else
		{
			float[] norm = MathHelper.normalize(dirX, dirY, new float[2]);
			dirX = norm[0];
			dirY = norm[1];
			dirX *= SPEED;
			dirY *= SPEED;
			player.px += dirX;
			player.py += dirY;
		}
	}

	public boolean isOutside(Edge e)
	{
		return isOutside(e.v1) && isOutside(e.v2); 
	}
	
	private boolean isOutside(Vertex v)
	{
		return v.px < 0 || v.px > WIDTH || v.py > HEIGHT;
	}
		
	public static void log(String msg, float x, float y)
	{
		System.out.println(msg+" ("+x+","+y+")");
	}	
}
